package com.xhh.nphm.framework.aspectj;

import com.xhh.nphm.common.annotation.ExecuteTimes;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @description: 切面
 * @author: sun
 * @date: 2023-08-03 14:35
 * @version 1.0
 */
@Slf4j
@Component
@Aspect
public class ExecuteTimesAspect {

    // 配置织入点
    @Pointcut("@annotation(com.xhh.nphm.common.annotation.ExecuteTimes)")
    public void executeTimesPointcut() {
    }

    //环绕通知
    @Around("executeTimesPointcut()")
    public  <T> T around(ProceedingJoinPoint pjp) throws Throwable {
        Long startTime = System.currentTimeMillis();
        Object[] args = pjp.getArgs();
        T result;
        Method methodClass;
        try {
            result = (T)pjp.proceed(args);//执行方法
        }finally {
            long endTime = System.currentTimeMillis();
            Signature signature = pjp.getSignature();
            String methodName = signature.getName();
            Class<?> targetClass = pjp.getTarget().getClass();
            Class[] parameterTypes = ((MethodSignature) pjp.getSignature()).getParameterTypes();
            methodClass = targetClass.getMethod(methodName, parameterTypes);
            Annotation[] annotations = methodClass.getAnnotations();
            for (Annotation annotation : annotations){
                Class<? extends Annotation> aClass = annotation.annotationType();
                String simpleName = aClass.getSimpleName();
                if("TimeConsume".equals(simpleName)){
                    ExecuteTimes timeConsume = (ExecuteTimes) annotation;
                    String value = timeConsume.value();
                    System.err.printf(value + "[%s] 执行耗时：%sms",methodName,endTime-startTime);
                    break;
                }
            }
        }
        return result;
    }

}
